除了fetch外,也有不少人用axios套件來處理AJAX,非常方便易用,Vue作者更建議使用axios作為HTTP請求工具。事實上,Axios是很輕量的套件,只有約13kb,比起引用笨重的jQuery來處理AJAX,axios是更可取的選擇。
承接昨天講解fetch的文章,今天會集中整理以下有關axios的知識:
.create
方法要引入axios,可以使用npm下載,也可以直接載入CDN。
axios的最基本語法:
axios(url[,config])
axios回傳的物件是Promise(fulfilled狀態),所以我們可以用.then
和.catch
去處理成功和失敗結果。
const x = axios('https://randomuser.me/api/')
x.then((response) => console.log(x)) //Promise {<fulfilled>: {…}}
axios默認是GET請求。所以最簡單的寫法可以是這樣:
axios('https://randomuser.me/api/')
.then( (response) => console.log(response))
.catch( (error) => console.log(error));
但實作上比較少見這樣簡寫,通常都是axios.get(...)
或者axios.post(...)
這種寫法比較多,接下來看看axio本身有提供的方法。
我們可以直接用axio
內建好的請求方法,例如是.get
和.post
:
//GET請求
axios.get('https://randomuser.me/api/')
.then( (response) => console.log(response))
.catch( (error) => console.log(error))
//POST請求
axios.post('https://hexschool-tutorial.herokuapp.com/api/signup',{
email: 'javascriptBasics@gmail.com',
password: '1234'
})
.then( (response) => console.log(response))
.catch( (error) => console.log(error))
這裏的GET要求使用了這個API,而POST要求使用了六角學院AJAX練習用的API,模擬註冊一個新帳號。
當然還有其他不同的方法可以直接使用:例如.delete
、.put
等等,詳細可看axios在github的readme,這裏不詳細寫了。
GET請求的参數設定:
當我們需要加入参數到URL時,我們可以直接寫在URL裏,也可以拆開放在params
裏面。
例如在random user的API裏,我想指定該User是女性及美國藉,那麼我就要在URL加入...api/?gender=female&nat=us
:
axios.get('https://randomuser.me/api/?gender=female&nat=us')
.then((response) => console.log(response)) //得出來的是類似Response的物件,裏面的data才是我們想抓的資料
.catch((error) => console.log(error))
另一個做法就是拆出來放在params裏面,這個做法與上面所做的事是一樣
axios.get('https://randomuser.me/api/',{
//URL参數放在params屬性裏面
params: {
gender: 'female',
nat: 'us'
}
})
.then((response) => console.log(response))
.catch((error) => console.log(error))
題外話,這裏也可以用asycn/await
去寫:
async function getUser(){
try{
const response = await axios.get('https://randomuser.me/api/?gender=female&nat=us');
console.log(response);
}catch(error){
console.log(error)
}
}
function getUserFemale(){
return axios.get('https://randomuser.me/api/?gender=female&nat=us')
};
function getUserMale(){
return axios.get('https://randomuser.me/api/?gender=male&nat=us')
};
Promise.all([getUserFemale(),getUserMale()])
.then( (response) => {
const femaleUser = response[0];
const maleUser = response[1];
console.log(femaleUser);
console.log(maleUser);
})
我們可以把所有東西(method
、url
、data
...)放在一個物件裏,這個物件我們稱為config。例如以下寫法:
//GET請求
axios({
method: 'get',
url: 'https://randomuser.me/api/?gender=female&nat=us'
})
.then((response) => console.log(response))
.catch((error) => console.log(error))
//POST請求
axios({
method: 'post',
url: 'https://hexschool-tutorial.herokuapp.com/api/signup',
//API要求的資料
data: {
email: 'alysa@gmail.com',
password: '11223344'
}
})
.then( (response) => console.log(response))
以上的POST例子中,我們把要傳送的資料(email,password)放在data
裏面。注意,data
不等於params
,兩者是不同的:
data
:傳送給伺服器的資料params
:在URL裏要加上的参數結果:
config物件裏,只有url
是必需的,其他都是可選。所以在一個config物件裏,可以包有很多屬性,例如以下的屬性:
axios({
method: 'post',
url: 'https://yourAPI/',
data: {
name: 'Mary',
age: 18
},
params: {
ID: 123456
},
// 添加在url前面,除非url是絕對路徑
baseURL: 'https://some-domain.com/api/'
}),
...})
這裏不詳細寫所有屬性,詳細可查看axio的readme。
另外,axios預設是傳送JSON格式,如果需要application/x-www-form-urlencoded
這種傳統的表單格式,就需要用qs
library去處理,官方的readme也有提及這一點。
.create
來預設axios裏的config物件axios有一個很方便的方法讓我們預設config,例子如下:
//在一個axios實體物件裏,設定預設的config物件
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
baseURL
:它會被添加在url
前面,例如我設定baseURL
是https://some-domain.com/api
,之後我傳入的URL是/productList
,最終的傳送去伺服器的URL就會是https://some-domain.com/api/productList
。headers
:發出請求的表頭,裏面放Authorization
、Content-Type
等等的東西。timeout
:如果發出請求時間出於timeout
所設定的時間,請求就會被中斷。利用.create
方法,我們就少寫一些重複的東西。例如不用每次都重寫整個api網址,因為api網址前面的部分都是一樣的,也不用每次都寫一次headers
。接下來會重用昨天六角學院的API例子,示範沒有使用.create
方法,以及有使用.create
方法的分別。
重用昨天六角學院的API例子,新增一個商品的API:
.create
,只用一般axios
的寫法const uuid = xxxxxx;
const token = xxxxxx;
//以下是六角學院提供的商品資料,我要把這商品新增到後台
let data = {
"title": "Abysswalker",
"category": "T-Shirts",
"content": "Its wearer, like Artorias himself, can traverse the Abyss.",
"description": "This official Dark Souls shirt was designed by Nina Matsumoto and printed on soft 100% cotton shirts by Forward. Each one comes with a bonus sticker.",
"imageUrl":['https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80'],
"enabled": true,
"origin_price": 680,
"price": 580,
"unit": "Item"
}
//請求表頭
let headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": `Bearer ${token}`,
};
//新增商品到後台
axios({
method: 'post',
url: `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/product`,
data: data,
headers: headers
})
.then( (response) => console.log(response))
.catch( (error) => console.log(error))
結果:
如果之後我要查看所有商品,我又要多寫一次header和整個URL:
//查看所有在後台的商品
axios({
method: 'get',
//又要多寫一次整個URL
url: `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/products`,
//又要多寫一次headers
headers: headers
})
.then( (response) => console.log(response))
.catch( (error) => console.log(error))
.create
方法用.create
的方法,就可以不用重複寫整個URL,也不用重複寫headers
,程式碼會更簡短易讀。
首先用.create
方法預設好config物件:
const uuid = xxxxxx;
const token = xxxxxx;
//新增一個變數叫HexSchool api,它是一個axios實體物件。
//我們在裏面設定config物件,讓我們之後可以重用
const apiHexSchool = axios.create({
baseURL: `https://course-ec-api.hexschool.io/api/${uuid}`,
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": `Bearer ${token}`,
}
})
之後,新增商品到後台時,直接拿apiHexSchool
這個axios物件來用,並在此物件使用POST方法:
let data = {
"title": "Abysswalker",
"category": "T-Shirts",
"content": "Its wearer, like Artorias himself, can traverse the Abyss.",
"description": "This official Dark Souls shirt was designed by Nina Matsumoto and printed on soft 100% cotton shirts by Forward. Each one comes with a bonus sticker.",
"imageUrl":['https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80'],
"enabled": true,
"origin_price": 680,
"price": 580,
"unit": "Item"
}
//新增商品到後台。在.post()裏第一個参數,只需放入URL後面的部分
const addProduct_backend = data => apiHexSchool.post('/admin/ec/product',data);
addProduct_backend(data)
.then( (response) => console.log(response))
.catch( (error) => console.log(error));
結果:
接著,如果我要查看所有商品,我只需要這樣寫:
//查看後台所有商品
const getProductList_backend = () => apiHexSchool.get('/admin/ec/products');
getProductList_backend()
.then( (response) => console.log(response))
.catch( (error) => console.log(error));
結果:
(因為之前練習時也新增了一些商品,所以這裏的商品數量會是7,請無視陣列的長度。)
總括來說,每一次接API,我只需重用apiHexSchool
這個axios實體物件就行了。因為這個實體物件裏已經設定好我想要的config,所以每次接API時,我不用重寫多一次config物件。
關於.create
這個方法,它也能幫助管理好我們在程式碼所接的API。這裏推薦閱讀Mike老師的這篇文章,他提及實作時我們可能要接幾十個API,我們可以先把這些API作一個簡單分類,然後為每一個類別,用.create
的方法建立axios實物,裏面設定好config物件。之後,當我們要接API時,就對應和引用之前建立好的axios物件。這裏就可以提升程式碼的可讀性,也便於管理所有API。
axios和fetch都是常見用來處理AJAX的語法,對於習慣Vue開發的人,可能用axios會比較多。明天會開始講解有關接API時會遇上的問題,以及一些除錯或解決方法~
使用Axios你的API都怎麼管理?
axios 基本使用 & Config
AJAX 完整解說系列:新增、更新、刪除(POST、PATCH、DELETE
由前端request 的幾種方法